﻿using System;
using System.Threading;
using Common.Devices.Comm.Model;

namespace Common.Devices.Comm
{
    /// <summary>
    /// tcp客户端
    /// </summary>
    public class TcpClientHelper : ITransmission
    {
        private readonly string _ip;
        private readonly int _port;
        private System.Net.Sockets.TcpClient _client;
        public TcpClientHelper() : this(new TcpClientInfo())
        {
        }
        public TcpClientHelper(TcpClientInfo info)
        {
            Parameter = info;
            _ip = info.Ip;
            _port = info.Port;
        }
        public TcpClientHelper(string ip, int port) : this(new TcpClientInfo()
        {
            Ip = ip,
            Port = port
        })
        {
        }

        public CommParameter Parameter { get; set; }
        public event Action<byte[]> Received;
        public bool Close()
        {
            _client.Client?.Close();
            _client?.Close();
            _client = null;
            _connectionState = false;
            _threadReceive.Abort();
            return true;
        }
        /// <summary>
        ///长连接 接受线程
        /// </summary>
        private Thread _threadReceive;
        /// <summary>
        /// 长连接接受标志
        /// </summary>
        private bool _longReceiveMark = true;
        /// <summary>
        /// 连接状态
        /// </summary>
        private bool _connectionState;
        public bool IsOpen()
        {
            return _connectionState;
        }

        public bool Open()
        {
            try
            {
                _client = new System.Net.Sockets.TcpClient(_ip, _port);
                _threadReceive?.Abort();//关闭以前的线程
                //创建线程 监听服务器 发来的消息
                _threadReceive = new Thread(() =>
                {
                    while (_longReceiveMark)
                    {
                        try
                        {
                            //尝试连接中如果没有消息会产生阻塞 
                            byte[] buf = new byte[8192];
                            //会产生阻塞
                            var size = _client.Client.Receive(buf);
                            byte[] data = new byte[size];
                            //返回数据
                            if (size > 0)
                            {
                                Array.Copy(buf, data, size);
                            }
                            Received?.Invoke(data);
                        }
                        catch (Exception)
                        {
                            // ignored
                        }
                    }

                })
                {
                    IsBackground = true//设置为后台线程
                };
                _threadReceive.Start(); //开启线程
                _connectionState = true;
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        public bool Send(byte[] buffer)
        {
            try
            {
                if (!IsOpen())
                {
                    Open();
                }
                _client.Client.Send(buffer);
                return true;
            }
            catch (Exception)
            {
                // ignored
            }

            return false;
        }

    }
}
